package com.gateway.video.rtsp.server.handler;

import com.gateway.video.rtsp.server.VideoServerConstants;
import com.gateway.video.rtsp.server.handler.support.RtspRequest;
import io.netty.channel.*;
import io.netty.handler.codec.http.*;
import io.netty.util.concurrent.Promise;
import lombok.extern.slf4j.Slf4j;
import lombok.var;

import java.nio.charset.Charset;
import java.util.ServiceLoader;

import static io.netty.channel.ChannelFutureListener.CLOSE;

@Slf4j
public class RtspServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        ctx.read();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if(msg instanceof HttpRequest) {
            var request = (HttpRequest) msg;

            handlerRequest(ctx, request, ctx.executor().<FullHttpResponse>newPromise().addListener(future -> {
                var response = (FullHttpResponse) future.getNow();
                if(future.isSuccess()) {
                    if(log.isDebugEnabled()) {
                        log.debug("Video server send response {} success. {}", request.method(), response);
                    }
                    ctx.read();
                }else {
                    if(log.isErrorEnabled()) {
                        log.error("Video server send response {} fail", request.method(), future.cause());
                    }
                    ctx.writeAndFlush(VideoServerConstants.ERROR_RESPONSE).addListener(CLOSE);
                }
            }));
        }
    }

    private void handlerRequest(ChannelHandlerContext ctx, HttpRequest request, Promise<FullHttpResponse> promise) {
        var rtspRequests = ServiceLoader.load(RtspRequest.class).iterator();
        while (rtspRequests.hasNext()) {
            var next = rtspRequests.next();
            if(next.isSupport(request)) {
                next.handler(ctx, request, promise);
            }
        }
    }
}
